// Copyright 2010 Christophe Henry
// henry UNDERSCORE christophe AT hotmail DOT com
// This is an extended version of the state machine available in the boost::mpl library
// Distributed under the same license as the original.
// Copyright for the original version:
// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
// under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)



namespace msm = boost::msm;
namespace mpl = boost::mpl;
using namespace msm::front;

namespace sm
{

    static string state_names[] = { "Sleeping", "Occurring", "Paused" };

    // events
    struct start 
    {
    	debug dbg;
	start()
	{
		dbg.log(__PRETTY_FUNCTION__, "event:start ");
	}
    };
    struct stop 
    {
    	debug dbg;
	stop()
	{
		dbg.log(__PRETTY_FUNCTION__, "event:stop");
	}
    };
    struct pause 
    {
    	debug dbg;
	pause()
	{
		dbg.log(__PRETTY_FUNCTION__, "event:pause");
	}
    };
    struct resume 
    {
    	debug dbg;
	resume()
	{
		dbg.log(__PRETTY_FUNCTION__, "event:resume");
	}
    };
    struct abort 
    {
    	debug dbg;
	abort()
	{
		dbg.log(__PRETTY_FUNCTION__, "event:abort");
	}
    };
	
    // Concrete FSM implementation 
    struct player_ : public msm::front::state_machine_def<player_>
    {
	string id;
	
	public:
	void setId(string i)
	{
		id=i;
	}

	string getId()
	{
		return id;
	}

        // no need for exception handling or message queue
        typedef int no_exception_thrown;
        typedef int no_message_queue;

        // The list of FSM states
        struct Sleeping : public msm::front::state<> 
        { 
    		debug dbg;
            template <class Event,class FSM>
            void on_entry(Event const&,FSM& ) 
		{
			dbg.log("Sleeping", __FUNCTION__, "state");
		}
            template <class Event,class FSM>
            void on_exit(Event const&,FSM& ) 
		{
			dbg.log("Sleeping", __FUNCTION__, "state");
		}
        };

        struct Occurring : public msm::front::state<>
        {
    		debug dbg;
            template <class Event,class FSM>
            void on_entry(Event const&,FSM& ) 
		{
			dbg.log("Occurring", __FUNCTION__, "state");
		}
            template <class Event,class FSM>
            void on_exit(Event const&,FSM& ) 
		{
			dbg.log("Occurring", __FUNCTION__, "state");
		}
        };

        struct Paused : public msm::front::state<>
        {
    		debug dbg;
            template <class Event,class FSM>
            void on_entry(Event const&,FSM& ) 
		{
			dbg.log("Paused", __FUNCTION__, "state");
		}
            template <class Event,class FSM>
            void on_exit(Event const&,FSM& ) 
		{
			dbg.log("Paused", __FUNCTION__, "state");
		}
        };

        // the initial state of the player SM. Must be defined
        typedef Sleeping initial_state;
        // transition actions
        struct starts
        {
    		debug dbg;
            template <class FSM,class EVT,class SourceState,class TargetState>
            void operator()(EVT const& ,FSM&,SourceState& ,TargetState& )
            {
		dbg.log("starts",__FUNCTION__, "transition::starts");
            }
        };
        struct stops 
        {
    		debug dbg;
            template <class FSM,class EVT,class SourceState,class TargetState>
            void operator()(EVT const& ,FSM&,SourceState& ,TargetState& )
            {
		dbg.log("stops",__FUNCTION__, "transition::stops ");
            }
        };
        struct pauses
        {
    		debug dbg;
            template <class FSM,class EVT,class SourceState,class TargetState>
            void operator()(EVT const& ,FSM&,SourceState& ,TargetState& )
            {
		dbg.log("pauses",__FUNCTION__, "transition::pauses ");
            }
        };
        struct resumes
        {
    		debug dbg;
            template <class FSM,class EVT,class SourceState,class TargetState>
            void operator()(EVT const& ,FSM&,SourceState& ,TargetState& )
            {
		dbg.log("resumes",__FUNCTION__, "transition::resumes ");
            }
        };
        struct aborts
        {
    		debug dbg;
            template <class FSM,class EVT,class SourceState,class TargetState>
            void operator()(EVT const& ,FSM&,SourceState& ,TargetState& )
            {
		dbg.log("aborts",__FUNCTION__, "transition::aborts ");
            }
        };

        struct noop 
        {
    		debug dbg;
            template <class FSM,class EVT,class SourceState,class TargetState>
            void operator()(EVT const& ,FSM&,SourceState& ,TargetState& )
            {
		dbg.log("noop",__FUNCTION__, "transition::noop ");
            }
        };

        // Transition table for player
        struct transition_table : mpl::vector<
            //    Start       Event        Next        Action                Guard
            //    +-----------+------------+-----------+---------------------+----------------------+
              Row < Sleeping  , start      , Occurring , starts                                   >,
            //  Row < Sleeping  , stop       , Sleeping  , noop                                	  >,
            //  Row < Sleeping  , pause      , Sleeping  , noop                                     >,
            //  Row < Sleeping  , resume     , Sleeping  , noop                                     >,
            //  Row < Sleeping  , abort      , Sleeping  , noop                                     >,
            //    +-----------+------------+-----------+---------------------+----------------------+
            //  Row < Occurring , start      , Occurring , noop		                          >,
              Row < Occurring , stop       , Sleeping  , stops                                    >,
              Row < Occurring , pause      , Paused    , pauses                                   >,
            //  Row < Occurring , resume     , Occurring , noop                                     >,
              Row < Occurring , abort      , Sleeping  , aborts                                   >,
            //    +-----------+------------+-----------+---------------------+----------------------+
            //  Row < Paused    , start      , Paused    , noop                                     >,
              Row < Paused    , stop       , Sleeping  , stops                                    >,
            //  Row < Paused    , pause      , Paused    , noop                                     >,
              Row < Paused    , resume     , Occurring , resumes                                  >,
              Row < Paused    , abort      , Sleeping  , aborts                                   >
            //    +-----------+-------------+---------+---------------------+----------------------+
        > {};

        // Replaces the default no-transition response.
        template <class FSM,class Event>
        void no_transition(Event const& e, FSM&,int state)
        {
            	std::cout << "no transition from state " << state
                << " on event " << typeid(e).name() << std::endl;
        }
    };

    typedef msm::back::state_machine<player_> player;

    //
    // Testing utilities.
    //

/*
    void pstate(player const& p)
    {
        std::cout << " -> " << state_names[p.current_state()[0]] << std::endl;
    }
*/

}

/*
int main()
{
    sm::player p;
    p.start();
    p.process_event(sm::start());      
    sm::pstate(p);
    p.process_event(sm::pause()); 
    p.process_event(sm::resume()); 
    p.process_event(sm::stop());  
    sm::pstate(p);
    p.process_event(sm::stop());
    p.process_event(sm::start());
    p.process_event(sm::abort());
    sm::pstate(p);
    return 0;
}
*/
